#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Author: leuelcey (wyd)
# E-mail: leuelcey@163.com
# Creation date: 2021.2
# Modified date: 2021.4

from sys import path as spath
from os import path as opath
from math import asin, pi as PI
spath.append('..')
from Common.config import Config

dconf = Config()
class BasicData(object):
    """
    基础数据类。
    """
    __slots__ = ('_configd', '_datafile', 'shengs', 'tacitjw')

    def __init__(self):
        super(BasicData, self).__init__()
        self._configd = {}
        self._datafile = 'datas/basicdata.cfg'
        self.tacitjw = 'dshO'  # 默认为北京市经纬度
        self.shengs = self._hq_shengs()  # 各省名清单

    # by leuelcey (wyd)
    def get_constant(self, *, section, varname='ALL', subname='', subpart=-1):
        if not section:
            return {}
        if self._configd:
            self._configd = {}

        if section == 'astronomy':
            single = self._get_astr_const(varname=varname)
            return single
        if section == 'bazi':
            single = self._get_bazi_const(varname=varname)
            return single
        if section == 'yijing':
            single = self._get_zhyi_const(varname=varname)
            return single
        if section == 'calendar':
            single = self._get_cale_const(varname=varname)
            return single
        if not self._datafile:
            return {}
        self._get_base_datas(section=section, varname=varname, subname=subname, subpart=subpart)
        return self._configd

    # 数据提供者：许剑伟（莆田十中）
    # by leuelcey (wyd)
    def _get_astr_const(self, varname):
        # 对应原常量 cs_rEar，地球赤道半径(千米)
        self._configd['equator_radius'] = 6378.1366
        # 对应原常量 cs_rEarA，平均半径
        self._configd['average_radius'] = 0.99834 * self._configd['equator_radius']
        # 对应原常量 cs_ba，地球极赤半径比
        self._configd['radius_ratio'] = 0.99664719
        # 对应原常量 cs_ba2，地球极赤半径比的平方
        self._configd['radius_ratio_m2'] = self._configd['radius_ratio'] * self._configd['radius_ratio']
        # 对应原常量 cs_AU，天文单位长度(千米)
        self._configd['unit_length'] = 1.49597870691e8
        # 对应原常量 cs_sinP，太阳视差的 sin 值
        self._configd['sin_solar_parallax'] = self._configd['equator_radius'] / self._configd['unit_length']
        # 对应原常量 cs_PI，太阳视差
        self._configd['solar_parallax'] = asin(self._configd['sin_solar_parallax'])
        # 对应原常量 cs_GS，光速(行米/秒)
        self._configd['light_speed'] = 299792.458
        # 对应原常量 cs_Agx，每天文单位的光行时间(儒略世纪)
        self._configd['travel_time'] = self._configd['unit_length'] / self._configd['light_speed'] / 86400 / 36525
        # 对应原常量 cs_xxHH，太阳系行星会合周期
        self._configd['join_period'] = (116, 584, 780, 399, 378, 370, 367, 367)
        # 对应原常量 xxName，行星名称
        self._configd['planet_name'] = ('地球', '水星', '金星', '火星', '木星', '土星', '天王星', '海王星', '冥王星')
        # 对应原常量 rad，每弧度的角秒数
        self._configd['radian_arcsec'] = 180.0 * 3600.0 / PI
        # 对应原常量 radd，每弧度的度数
        self._configd['radian_degree'] = 180.0 / PI
        # 对应原常量 pi2，2倍圆周率
        self._configd['pi_2times'] = PI * 2.0
        # 对应原常量 pi_2，1/2圆周率
        self._configd['pi_ahalf'] = PI / 2.0
        # 对应原常量 J2000，2000年前儒略日数(2000-1-1 12:00:00格林威治平时)
        self._configd['J2000'] = 2451545
        # 对应原常量 cs_k，月亮与地球的半径比(用于半影计算)
        self._configd['used_4penumbra'] = 0.2725076
        # 对应原常量 cs_k2，月亮与地球的半径比(用于本影计算)
        self._configd['used_4umbra'] = 0.2722810
        # 对应原常量 cs_k0，太阳与地球的半径比(对应959.64)
        self._configd['radius_ratio'] = 109.1222
        # 对应原常量 cs_sMoon，用于月亮视半径计算
        self._configd['used_4apparent1'] = self._configd['used_4penumbra'] * self._configd['equator_radius'] * 1.0000036 * self._configd['radian_arcsec']
        # 对应原常量 cs_sMoon2，用于月亮视半径计算
        self._configd['used_4apparent2'] = self._configd['used_4umbra'] * self._configd['equator_radius'] * 1.0000036 * self._configd['radian_arcsec']
        # 对应原常量 cs_sSun，用于太阳视半径计算
        self._configd['sun_apparent'] = 959.64
        if varname.upper() == 'ALL':
            return self._configd
        return self._configd[varname]

    # 数据提供者：许剑伟（莆田十中）
    # by leuelcey (wyd)
    def _get_bazi_const(self, varname):
        self._configd['gan'] = ("甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸")
        #                            0     1      2     3     4     5     6     7     8     9     10    11
        self._configd['zhi'] = ("子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥")
        self._configd['xiao'] = ("鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪")
        # 纳音
        self._configd['nayin'] = ("大海水", "海中金", "炉中火", "大林木", "路旁土", "剑锋金", "山头火", "洞下水", "城头土", "白腊金",
                                "杨柳木", "井泉水", "屋上土", "霹雳火", "松柏木", "长流水", "沙中金", "山下火", "平地木", "壁上土",
                                "金箔金", "覆灯火", "天河水", "大驿土", "钗钏金", "桑柘木", "大溪水", "沙中土", "天上火", "石榴木", "大海水")
        self._configd['nywx'] = {
                                "大海水": (4, 18), "海中金": (3, 18), "炉中火": (1, 2), "大林木": (0, 18), "路旁土": (2, 1), "剑锋金": (3, 6), 
                                "山头火": (1, 6), "涧下水": (4, 1), "城头土": (2, 9), "白腊金": (3, 2), "杨柳木": (0, 4), "井泉水": (4, 2), 
                                "屋上土": (2, 6), "霹雳火": (1, 9), "松柏木": (0, 6), "长流水": (4, 4), "沙中金": (3, 9), "山下火": (1, 4), 
                                "平地木": (0, 9), "壁上土": (2, 4), "金箔金": (3, 1), "覆灯火": (1, 1), "天河水": (4, 9), "大驿土": (2, 18), 
                                "钗钏金": (3, 4), "桑柘木": (0, 2), "大溪水": (4, 6), "沙中土": (2, 2), "天上火": (1, 18), "石榴木": (0, 1)
        }
        # 十神，按木火土金水五行顺序排序
        self._configd['shishen'] = {'比劫': ('比肩', '劫财'), '食伤': ('食神', '伤官'), '财星': ('偏财', '正财'), '官杀': ('七杀', '正官'), '枭印': ('偏印', '正印')}
        self._configd['zhi_gan'] = (8, 5, 0, 2, 4, 3, 2, 5, 6, 7, 4, 9)  # 地支转天干
        self._configd['wuxing'] = ('木', '火', '土', '金', '水')  # 五行
        self._configd['zhi_wx'] = (4, 2, 0, 0, 2, 1, 1, 2, 3, 3, 2, 4)  # 地支对应五行
        self._configd['gan_wx'] = (0, 0, 1, 1, 2, 2, 3, 3, 4, 4)  # 天干对应五行
        # 十二长生位置，其天干对应的地支索引
        self._configd['gan_zhi'] = (11, 6, 2, 9, 2, 9, 5, 0, 8, 3)
        # 地支藏干
        self._configd['cangan'] = ([9], [5,7,9], [0,2,4], [1], [4,9,1], [2,6,4], [3,5], [5,1,3], [6,8,4], [7], [4,3,7], [8,0])
        # 十二长生
        self._configd['zhangsheng'] = ("长生", "沐浴", "冠带", "临官", "帝旺", "衰", "病", "死", "墓", "绝", "胎", "养")
        self._configd['benqi'] = ('禄', '刃', '长生', '墓库', '余气', '死', '绝')  # 本气
        # 星煞
        self._configd['xing_sha'] = ('空亡', '天乙', '太极', '天医', '天德', '月德', '禄神', '羊刃', '孤鸾', '三奇',
                                        '天赦', '德秀', '魁罡', '金神', '天罗', '地网', '文昌', '金舆', '福星', '国印',
                                        '天厨', '学堂', '红艳', '流霞', '将星', '华盖', '驿马', '劫煞', '亡神', '元辰(大耗)',
                                        '孤辰', '寡宿', '灾煞', '六厄', '勾煞', '绞煞', '童子', '词馆', '红鸾', '天喜',
                                        '桃花', '干禄', '十灵', '十恶大败'
        )

        self._configd['zhou'] = ()  # 洲名
        self._configd['guojia'] = ()  # 国名
        self._configd['sheng'] = self.shengs  # 省名

        if varname.upper() == 'ALL':
            return self._configd
        return self._configd[varname]

    # by leuelcey (wyd)
    def _get_zhyi_const(self, varname):
        # 八卦信息，含卦名、卦象、各爻(从下向上的顺序)
        self._configd['bagua'] = (
                                    {'gua': '坤', 'xiang': '☷', 'yao': '666'},
                                    {'gua': '乾', 'xiang': '☰', 'yao': '999'},
                                    {'gua': '兑', 'xiang': '☱', 'yao': '996'},
                                    {'gua': '离', 'xiang': '☲', 'yao': '969'},
                                    {'gua': '震', 'xiang': '☳', 'yao': '966'},
                                    {'gua': '巽', 'xiang': '☴', 'yao': '699'},
                                    {'gua': '坎', 'xiang': '☵', 'yao': '696'},
                                    {'gua': '艮', 'xiang': '☶', 'yao': '669'}
                                )
        self._configd['najia'] = ('', '乾', '坤', '艮', '兑', '坎', '离', '震', '巽', '乾', '坤')
        self._configd['nazhi'] = ('', '坎', '艮', '艮', '震', '巽', '巽', '离', '坤', '坤', '兑', '乾', '乾')
        self._configd['fangwei'] = {
                'xiantian': {'东': '离', '西': '坎', '南': '乾', '北': '坤', '东南': '兑', '西南': '巽', '西北': '艮', '东北': '震'},
                'houtian': {'东': '震', '西': '兑', '南': '离', '北': '坎', '东南': '巽', '西南': '坤', '西北': '乾', '东北': '艮'}
        }
        if varname.upper() == 'ALL':
            return self._configd
        return self._configd[varname]

    # 数据提供者：许剑伟（莆田十中）
    # by leuelcey (wyd)
    def _get_cale_const(self, varname):
        self._configd['jieqi'] = ('冬至', '小寒', '大寒', '立春', '雨水', '惊蛰', '春分', '清明', '谷雨', '立夏', '小满', '芒种', '夏至', '小暑', '大暑', '立秋', '处暑', '白露', '秋分', '寒露', '霜降', '立冬', '小雪', '大雪')
        self._configd['Zodiac'] = ('摩羯','水瓶','双鱼','白羊','金牛','双子','巨蟹','狮子','处女','天秤','天蝎','射手')
        self._configd['yming'] = ('冬', '腊', '正', '二', '三', '四', '五', '六', '七', '八', '九', '十')
        self._configd['rming'] = ('初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十', '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十', '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十', '卅一')
        self._configd['Weeks'] = ('日', '一', '二', '三', '四', '五', '六', '七')
        self._configd['shuzi'] = ('零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十')
        self._configd['xiang'] = ("朔", "上弦", "望", "下弦")

        if varname.upper() == 'ALL':
            return self._configd
        return self._configd[varname]

    # 数据提供者：许剑伟（莆田十中）
    # by leuelcey (wyd)
    def _get_base_datas(self, *, section, varname, subname, subpart):
        if not opath.exists(self._datafile):
            self._configd = {}
        else:
            self._configd, _ = dconf.getConfig(filename=self._datafile, sec_name=section, var_name=varname, sub_name=subname, sub_part=subpart)

    # 数据提供者：许剑伟（莆田十中）
    # by leuelcey (wyd)
    def _hq_shengs(self):
        shpers, _ = dconf.getConfig(filename=self._datafile, sec_name='Position', var_name='China')

        shengs = ['' for x in range(len(shpers))]
        for k, v in enumerate(shpers):
            sheng = v.split(' ')[0]
            shengs[k] = sheng
        return shengs

    # by leuelcey (wyd)
    def hq_jwcode(self, sheng, quyu):
        if not sheng or not quyu:
            return self.tacitjw

        if not self.shengs:
            self.shengs = self._hq_shengs()
        if sheng not in self.shengs:
            return self.tacitjw

        shindex = self.shengs.index(sheng)
        qydatas, _ = dconf.getConfig(filename=self._datafile, sec_name='Position', var_name='China', sub_part=shindex)
        if quyu not in qydatas:
            return self.tacitjw

        qyming = qydatas.split(' ')[1:]
        qyindex = 0
        for k, v in enumerate(qyming):
            if quyu in v:
                qyindex = k
                break
            if qyindex != -1:
                qyindex = -1
        if qyindex == -1:
            return self.tacitjw
        return qyming[qyindex][:4]

